home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XAAES_S.ZIP / XAAES / FORMS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-01  |  12.6 KB  |  520 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include "XA_DEFS.H"
  11. #include "XA_TYPES.H"
  12. #include "XA_GLOBL.H"
  13. #include "K_DEFS.H"
  14. #include "OBJECTS.H"
  15. #include "FRM_ALRT.H"
  16. #include "STD_WIDG.H"
  17. #include "C_WINDOW.H"
  18. #include "WATCHBOX.H"
  19. #include "FORM_DO.H"
  20.  
  21. #if 0
  22. #define CLIP(tree,obj,x,y,w,h)                \
  23.     object_abs_coords(tree, obj, &x, &y);    \
  24.     w = tree[obj].ob_width;                    \
  25.     h = tree[obj].ob_height;                \
  26.     set_clip(x, y, w, h);
  27. #endif
  28.  
  29. #define CLIP(tree,obj,x,y,w,h)    clear_clip()
  30. #define set_clip(x,y,w,h)        /* We don't want this now! */
  31.  
  32. #if 0
  33. #undef CLIP            /* Those set_clip(..) can't be useful */
  34. #endif
  35.  
  36. /*
  37.     FORM HANDLERS INTERFACE
  38. */
  39.  
  40. #if 0
  41. extern XA_WINDOW *window_list;        /* The global system window stack */
  42. #endif
  43.  
  44. /*
  45.     Primitive version of form_center....
  46.     -this ignores shadows & stuff
  47. */
  48. unsigned long XA_form_center(short clnt_pid, AESPB *pb)
  49. {
  50.     OBJECT *ob = pb->addrin[0];
  51.     short x, y, w, h;
  52.     
  53.     w = ob->ob_width;
  54.     h = ob->ob_height;
  55.     
  56.     x = (display.w - w) / 2;
  57.     y = (display.h - h) / 2;
  58.     
  59.     ob->ob_x = x;
  60.     ob->ob_y = y;
  61.     
  62.     pb->intout[0] = 1;
  63.     pb->intout[1] = x;
  64.     pb->intout[2] = y;
  65.     pb->intout[3] = w;
  66.     pb->intout[4] = h;
  67.     
  68.     return XAC_DONE;
  69. }
  70.  
  71. /*
  72.   Begin/end form handler
  73.   This is important - I hope most programs call this, as XaAES puts it's dialogs
  74.   in windows, and the windows are created here....
  75. */
  76. unsigned long XA_form_dial(short clnt_pid, AESPB *pb)
  77. {    
  78.     XA_CLIENT *client=Pid2Client(clnt_pid);
  79.     XA_WINDOW *dialog_window;
  80.     short x, y, w, h;
  81.  
  82.     switch(pb->intin[0])
  83.     {
  84.         case FMD_START:             /* Create a window to put the dialog in */
  85.  
  86.             dialog_window = create_window(clnt_pid, NAME, pb->intin[5], pb->intin[6], 
  87.                             pb->intin[7], pb->intin[8]);
  88.  
  89.             x = 2 * dialog_window->x - dialog_window->wx;
  90.             y = 2 * dialog_window->y - dialog_window->wy;
  91.             w = 2 * dialog_window->w - dialog_window->ww + 1;
  92.             h = 2 * dialog_window->h - dialog_window->wh + 1;
  93.  
  94.             delete_window(dialog_window);        /* Dispose of the temporary window we created */
  95.                                                 /* And create the real one. It stay's fixed until form_do is called */
  96.                                                 /* when it gets a MOVE property. */
  97. /* We create a window owned by the client so it will get button clicks for this area (in case it's gonna handle things it's own way) */
  98.             client->zen = dialog_window = create_window(clnt_pid, NAME | STORE_BACK | NO_MESSAGES | NO_WORK, x, y, w, h);
  99.             dialog_window->is_open = TRUE;
  100.             dialog_window->created_by_FMD_START = TRUE;
  101. /* Set the window title to be the clients name to avoid confusion */
  102.             dialog_window->widgets[XAW_TITLE].stuff = (void*)client->name;
  103.  
  104.             v_hide_c(V_handle);
  105.             pull_wind_to_top(dialog_window);
  106.             display_window(dialog_window);
  107.             v_show_c(V_handle, 1);
  108.             
  109.             break;
  110.         case FMD_GROW:
  111.             break;
  112.         case FMD_SHRINK:
  113.             break;
  114.         case FMD_FINISH:        /* If the client's dialog window is still hanging around, dispose of it.... */
  115.             dialog_window = client->zen;
  116.             if (dialog_window)
  117.             {
  118.                 v_hide_c(V_handle);
  119.                 display_windows_below(dialog_window);
  120.                 v_show_c(V_handle, 1);
  121.  
  122.                 dialog_window->is_open = FALSE;
  123.  
  124.                 delete_window(dialog_window);
  125.                 client->zen = NULL;
  126.             }
  127.             break;
  128.     }
  129.     
  130.     pb->intout[0] = 1;
  131.     
  132.     return XAC_DONE;
  133. }
  134.  
  135. unsigned long XA_form_button(short clnt_pid, AESPB *pb)
  136. {
  137.     OBJECT *tree = (OBJECT*)pb->addrin[0];
  138.     short ob = pb->intin[0];
  139.     short is, os, x, y, w, h;
  140.  
  141.     pb->intout[1] = 0;
  142.  
  143.     if (tree[ob].ob_flags & EDITABLE)    /* Select a new editable text field? */
  144.     {
  145.     /*    
  146.      * Shouldn't this really do all that's done in form_do?
  147.      */
  148.  
  149.         pb->intout[1] = ob;
  150.     }
  151.  
  152.     if (((tree[ob].ob_flags & HIDETREE)        /* Was click on a valid selectable object? */
  153.         ||(tree[ob].ob_state & DISABLED))
  154.         ||(!(tree[ob].ob_flags & (SELECTABLE | EXIT | TOUCHEXIT))))
  155.     {
  156.         pb->intout[0] = 1;
  157.         return XAC_DONE;
  158.     }
  159.  
  160.     CLIP(tree, ob, x, y, w, h);
  161.  
  162.     os = tree[ob].ob_state;
  163.     is = os ^ SELECTED;
  164.  
  165.     if (tree[ob].ob_flags & TOUCHEXIT)        /* Change state & exit for TOUCHEXIT objects */
  166.     {
  167. /*
  168.  * Surely radio buttons must be handled as well?
  169.  */
  170.         /* Only selectable objects change appearance! */
  171.         if (tree[ob].ob_flags & SELECTABLE)
  172.         {
  173.             tree[ob].ob_state = is;
  174.             v_hide_c(V_handle);
  175.             draw_object_tree(tree, ob, MAX_DEPTH);
  176.             v_show_c(V_handle, 1);
  177.         }
  178.  
  179.         pb->intout[1] = ob;
  180.         
  181.         pb->intout[0] = 0;
  182.         
  183.         if (pb->intin[1] == 2)    /* Double click? */
  184.         {
  185.             pb->intout[1] |= 0x8000;
  186.         }
  187.         
  188.         return XAC_DONE;
  189.     }
  190.  
  191. /*
  192.  * Should this perhaps be done in watch_object()?
  193.  */
  194.     tree[ob].ob_state = is;
  195.     CLIP(tree, ob, x, y, w, h);
  196.     v_hide_c(V_handle);
  197.     draw_object_tree(tree, ob, MAX_DEPTH);
  198.     v_show_c(V_handle, 1);
  199.         
  200.     if (watch_object(tree, ob, is, os))        /* Do a watch to see if object is really selected */
  201.     {
  202.         if (!(tree[ob].ob_flags&SELECTABLE))
  203.         {
  204.             tree[ob].ob_state=os;
  205.             v_hide_c(V_handle);
  206.             draw_object_tree(tree,ob,2);
  207.             v_show_c(V_handle,1);
  208.         }
  209. /*
  210.  * Surely this should check for radio buttons?
  211.  */
  212.          if (tree[ob].ob_flags & EXIT)
  213.         {
  214.             pb->intout[1] = ob;
  215.             pb->intout[0] = 0;
  216. #ifdef CLIP
  217.             clear_clip();
  218. #endif
  219.             
  220.             return XAC_DONE;
  221.         }
  222.     }
  223.  
  224. #ifdef CLIP
  225.     clear_clip();
  226. #endif
  227.  
  228.     pb->intout[0] = 1;
  229.     return XAC_DONE;
  230.  
  231. unsigned long XA_form_alert(short clnt_pid, AESPB *pb)
  232. {
  233.     XA_CLIENT *client=Pid2Client(clnt_pid);
  234.     client->waiting_pb = pb;
  235.     
  236.     do_form_alert(pb->intin[0], (char*)pb->addrin[0], clnt_pid);
  237.  
  238.     return XAC_BLOCK;
  239. }
  240.  
  241. char error_alert[100];
  242. unsigned long XA_form_error(short clnt_pid, AESPB *pb)
  243. {
  244.     XA_CLIENT *client=Pid2Client(clnt_pid);
  245.     char *msg;
  246.     char icon;
  247.  
  248.     client->waiting_pb = pb;
  249.     
  250.     switch(pb->intin[0])
  251.     {
  252.         case 2:
  253.             msg = "File not found.";
  254.             icon = '5';
  255.             break;
  256.         case 3:
  257.             msg = "Path not found.";
  258.             icon = '5';
  259.             break;
  260.         case 4:
  261.             msg = "No more file handles.";
  262.             icon = '5';
  263.             break;
  264.         case 5:
  265.             msg = "Access denied.";
  266.             icon = '5';
  267.             break;
  268.         case 8:
  269.             msg = "Insufficient memory.";
  270.             icon = '6';
  271.             break;
  272.         case 10:
  273.             msg = "Invalid enviroment.";
  274.             icon = '6';
  275.             break;
  276.         case 11:
  277.             msg = "Invalid format.";
  278.             icon = '6';
  279.             break;
  280.         case 15:
  281.             msg = "Invalid drive specification.";
  282.             icon = '5';
  283.             break;
  284.         case 16:
  285.             msg = "Attempt to delete working directory.";
  286.             icon = '5';
  287.             break;
  288.         case 18:
  289.             msg = "No more files.";
  290.             icon = '5';
  291.             break;
  292.         default:
  293.             msg = "Unknown error.";
  294.             icon = '7';
  295.             break;
  296.         
  297.     }
  298.     
  299.     sprintf(error_alert, "[%c][ ERROR: | %s ][ Bugger ]", icon, msg);
  300.     
  301.     do_form_alert(1, error_alert, clnt_pid);
  302.  
  303.     return XAC_BLOCK;
  304. }
  305.  
  306. /*
  307.     Non-blocking form_do
  308.     - uses an object tree widget in a window to implement the form handler.
  309. */
  310. unsigned long XA_form_do(short clnt_pid, AESPB *pb)
  311. {
  312.     XA_CLIENT *client=Pid2Client(clnt_pid);
  313.     XA_WINDOW *dialog_window;
  314.     OBJECT *form = (OBJECT*)pb->addrin[0];
  315.     XA_WIDGET_LOCATION dialog_toolbar_loc = {LT, 3, 20};
  316.     short x, y, w, h;
  317.     short startedit;
  318.     
  319.     DIAGS(("form_do()\n"));
  320.  
  321.     client->waiting_pb = pb;
  322.     
  323.     if (!client->zen)            /* If the client hasn't called FMD_START (naughty), create a window for the dialog */
  324.     {
  325.         dialog_window = create_window(clnt_pid, NAME | MOVE, form->ob_x, form->ob_y, form->ob_width, form->ob_height);
  326.  
  327.         x = 2 * dialog_window->x - dialog_window->wx;
  328.         y = 2 * dialog_window->y - dialog_window->wy;
  329.         w = 2 * dialog_window->w - dialog_window->ww + 1;
  330.         h = 2 * dialog_window->h - dialog_window->wh + 1;
  331.  
  332.         delete_window(dialog_window);        /* Dispose of the temporary window we created */
  333.  
  334.         client->zen = dialog_window = create_window(clnt_pid, NAME | MOVE | STORE_BACK | NO_MESSAGES | NO_WORK, x, y, w, h);
  335.  
  336.         dialog_window->created_by_FMD_START = FALSE;
  337.     /* Set the window title to be the clients name to avoid confusion */
  338.         dialog_window->widgets[XAW_TITLE].stuff = (void*)client->name;
  339.     }else{
  340.         dialog_window = client->zen;
  341.         dialog_window->owner = clnt_pid;
  342.         
  343. #if 0
  344.         v_hide_c(V_handle);
  345.         display_windows_below(dialog_window);
  346.         v_show_c(V_handle, 1);
  347. #endif
  348.     }
  349.     
  350. //    client->waiting_for=XAWAIT_DIALOG|XAWAIT_KEY;
  351.     client->waiting_for=XAWAIT_DIALOG;
  352.     dialog_toolbar_loc.y = display.c_max_h + 10;
  353.     set_toolbar_widget(dialog_window, dialog_toolbar_loc, form);
  354.     
  355.     /*
  356.      * If there is an editable field, we'll need a keypress handler.
  357.      */
  358.     
  359.     startedit = pb->intin[0];
  360.     if (!startedit) {    /* If there's no set edit_obj field, search */
  361.         short f = 0;
  362.         do {
  363.             if (form[f].ob_flags & EDITABLE) {
  364.                 startedit = f;
  365.                 break;
  366.             }
  367.             f++;
  368.         } while (!(form[f].ob_flags & LASTOB));
  369.     }
  370.     
  371.     ((XA_WIDGET_TREE*)dialog_window->widgets[XAW_TOOLBAR].stuff)->owner = clnt_pid;
  372.     ((XA_WIDGET_TREE*)dialog_window->widgets[XAW_TOOLBAR].stuff)->edit_obj = startedit;
  373.     ((XA_WIDGET_TREE*)dialog_window->widgets[XAW_TOOLBAR].stuff)->edit_pos = 0;    /* Needed? */
  374.     
  375.     if (startedit) {    /* Set up keypress handler if needed */
  376.         TEDINFO *te = (TEDINFO*)form[startedit].ob_spec;
  377.         short f = 0;
  378.  
  379.         do {                                /* Ensure that there aren't two fields flagged as the */
  380.             form[f].ob_state &= ~IS_EDIT;        /* current edit field */
  381.             f++;
  382.         } while(!(form[f].ob_flags & LASTOB));
  383.         
  384.         dialog_window->keypress = &handle_form_key;
  385.         form[startedit].ob_state |= IS_EDIT;
  386.         te->te_tmplen = strlen(te->te_ptext);
  387.         ((XA_WIDGET_TREE*)dialog_window->widgets[XAW_TOOLBAR].stuff)->edit_pos = te->te_tmplen;
  388.  
  389.         CLIP(form, startedit, x, y, w, h);
  390.         v_hide_c(V_handle);
  391.         draw_object_tree(form, startedit, 2);
  392.         v_show_c(V_handle, 1);
  393.     }
  394.  
  395.     dialog_window->active_widgets |= (NO_MESSAGES | MOVE);    /* We don't want any redraw messages  */
  396.                                             /* - the widget handler will take care of it */
  397.     dialog_window->is_open = TRUE;
  398.  
  399. #if 0
  400.     v_hide_c(V_handle);
  401.     pull_wind_to_top(dialog_window);
  402.     display_window(dialog_window);
  403.     v_show_c(V_handle, 1);
  404. #endif
  405.  
  406.     return XAC_BLOCK;
  407. }
  408.  
  409. short XA_form_keybd(short clnt_pid, AESPB *pb)
  410. {
  411.     OBJECT *form = pb->addrin[0];
  412.     short ed_obj = pb->intin[0];
  413.     short keycode = pb->intin[1];
  414.     TEDINFO *ed_txt;
  415.     char *txt;
  416.     short o, x, y, w, h, last_ob;
  417.     
  418.     DIAGS(("form_keybd():%x,%x,%x\n", pb->intin[0], pb->intin[1], pb->intin[2]));
  419.     
  420.     pb->intout[0] = 1;
  421.     pb->intout[1] = ed_obj;
  422.     pb->intout[2] = 0;
  423.     
  424.     if (!(form[ed_obj].ob_flags & EDITABLE))
  425.         return XAC_DONE;
  426.  
  427.     ed_txt = (TEDINFO*)form[ed_obj].ob_spec;
  428.     txt = ed_txt->te_ptext;
  429.  
  430.     switch(keycode)
  431.     {
  432.     case 0x0f09:        /* TAB moves to next field */
  433.     case 0x5000:        /* DOWN ARROW also moves to next field */
  434.         if (form[ed_obj].ob_flags & LASTOB)    /* Loop round */
  435.             o = 0;
  436.         else
  437.             o = ed_obj;
  438.                 
  439.         for(o++; !(form[o].ob_flags & EDITABLE); o++)        /* search for next editable object */
  440.         {
  441.             if (form[o].ob_flags & LASTOB)    /* Loop round */
  442.                 o = 0;
  443.         }
  444.                 
  445.         break;
  446.     
  447.     case 0x5032:        /* SHIFT+DOWN ARROW moves to last field */
  448.         for(last_ob = 0; !(form[last_ob].ob_flags & LASTOB); last_ob++) ; /*find last object*/
  449.         o = last_ob;
  450.         for(; !(form[o].ob_flags & EDITABLE); o--) ;        /* search for last editable object */
  451.         break;
  452.             
  453.     case 0x4800:    /* UP ARROW moves to previous field */
  454.         for(last_ob = 0; !(form[last_ob].ob_flags & LASTOB); last_ob++) ; /*find last object*/
  455.                 
  456.         if (ed_obj == 1)    /* Loop round ? */
  457.             o = last_ob + 1;
  458.         else
  459.             o = ed_obj;
  460.                     
  461.         for(o--; !(form[o].ob_flags & EDITABLE); o--)        /* search for previous editable object */
  462.         {
  463.             if (o == 1)    /* Loop round */
  464.                 o = last_ob + 1;
  465.         }
  466.                 
  467.         break;
  468.     
  469.     case 0x4838:        /* SHIFT+UP ARROW moves to first field */
  470.         o = 0;
  471.         for(o++; !(form[o].ob_flags & EDITABLE); o++) ;    /* search for first editable object */
  472.         break;
  473.                     
  474.     case 0x1c0d:    /* Return - select default (if any) */
  475.         o = 0;
  476.         do{
  477.             if (form[o].ob_flags & DEFAULT)
  478.             {
  479.                 pb->intout[0] = 0;
  480.                 pb->intout[1] = o;
  481.                 return XAC_DONE;
  482.             }
  483.             o++;
  484.         } while(!(form[o].ob_flags & LASTOB));
  485.         break;
  486.                 
  487.     default:        /* just a plain key - insert character */
  488.         DIAGS(("passing character back to client\n"));
  489.         pb->intout[2] = keycode;
  490.         break;
  491.     }
  492.     switch(keycode) {    /* Moved from four places above. */
  493.     case 0x0f09:        /* All the common updating is */
  494.     case 0x5000:        /* done here now. */
  495.     case 0x5032:
  496.     case 0x4800:
  497.     case 0x4838:
  498.         if (o != ed_obj)    /* If edit field has changed, update the display */
  499.         {
  500.             form[o].ob_state |= IS_EDIT;
  501.             form[ed_obj].ob_state &= ~IS_EDIT;
  502.             
  503.             CLIP(form, ed_obj, x, y, w, h);
  504.             v_hide_c(V_handle);
  505.             draw_object_tree(form, ed_obj, 2);
  506.  
  507.             ((TEDINFO*)form[o].ob_spec)->te_tmplen = strlen(((TEDINFO*)form[o].ob_spec)->te_ptext);
  508.             
  509.             CLIP(form, o, x, y, w, h);
  510.             draw_object_tree(form, o, 2);
  511.             v_show_c(V_handle, 1);
  512.                 
  513.             pb->intout[1] = o;
  514.         }
  515.     }
  516.     
  517.     return XAC_DONE;
  518. }
  519.